﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

using KaoQin.RFIDLIB;
using KaoQin.BLL;
using KaoQin.Common;
using KaoQin.Model;
using KaoQin.WebcamPlayer;
using System.Drawing;
using System.Drawing.Imaging;
using System.Media;

namespace KaoQin.swipingcard
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            //System.Threading.Thread.Sleep(3000); 
            InitializeComponent();
        }


        #region 变量


        private DispatcherTimer timer1;
        private DispatcherTimer timer2;
        private DispatcherTimer timer3;
        private DispatcherTimer timer4;
        private DateTime ActionTime = DateTime.Now;
        private Dictionary<string, SwipingInfo> emplist = new Dictionary<string, SwipingInfo>();
        private bool isRuning = false;
        private readonly object locker = new object();
        private string workNumber = string.Empty;
        private string password = string.Empty;
        private SysWorkTimeParasInfo timeParasInfo;
        private bool useWebcam = false;
        private bool byHand = false;
        private string cardID = string.Empty;
        private string onID = string.Empty;
        private SwipeCardRecord sbll;
        private SoundPlayer soundplayer;
        #endregion


        #region 初始化
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            try
            {
                initData();
                this.initParas();
                this.initWebcam();
            }
            catch (Exception ex)
            {
                ShowTip("初始化数据出错了：" + ex.Message);
            }


        }



        private void initParas()
        {
            string dacaWay = new SysParameters().GetModel(1).Value1;

            if (dacaWay == "0")
            {
                gboxHand.Visibility = Visibility.Collapsed;
            }
            else if (dacaWay == "1")
            {
                gboxHand.Visibility = Visibility.Visible;
                timer1.Stop();
            }
            else if (dacaWay == "2")
            {
                gboxHand.Visibility = Visibility.Visible;
            }
            else
            {
                gboxHand.Visibility = Visibility.Collapsed;
            }

            string fullScreen = new SysParameters().GetModel(2).Value1;

            if (fullScreen == "1")
            {
                if (!FullscreenHelper.IsFullscreen(this))
                {
                    FullscreenHelper.GoFullscreen(this);
                    btnFullScreen.Visibility = Visibility.Collapsed;
                }
            }

            
            
        }

        private void initWebcam()
        {
            SysWebcamParasInfo webcamParas = new SysWebcamParas().GetModel("48165275-EE69-4E01-A232-7BD4A9E28D4F");

            if (webcamParas != null && webcamParas.KState == 1)
            {


                CapDevice videoDevice = new CapDevice(webcamParas.value);
                if (videoDevice != null)
                {
                    webcamPlayer.Device = videoDevice;
                    webcamPlayer.Rotation = 180d;

                }
                else
                {
                    MessageBox.Show("请先登录系统进行视频设备设置");
                }
                useWebcam = true;



            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void initData()
        {
            timer1 = new DispatcherTimer();
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Interval = new TimeSpan(0, 0, 0, 0, 300);
            timer1.Start();


            //timer2 = new DispatcherTimer();
            //timer2.Tick += new EventHandler(timer2_Tick);
            //timer2.Interval = new TimeSpan(0, 0, 0, 20, 0);
            //timer2.Start();

            timer3 = new DispatcherTimer();
            timer3.Tick += new EventHandler(timer3_Tick);
            timer3.Interval = new TimeSpan(0, 0, 0, 1, 0);
            timer3.Start();

            timer4 = new DispatcherTimer();
            timer4.Tick += new EventHandler(timer4_Tick);
            timer4.Interval = new TimeSpan(0, 0, 0, 1, 0);
            timer4.Start();

            timeParasInfo = new SysWorkTimeParas().GetModel("435B4B55-817D-433E-BD50-1CEAB38DFDC8");

            sbll = new SwipeCardRecord();

            soundplayer = new SoundPlayer();
            soundplayer.SoundLocation = "xiexie.wav";

        }

        #endregion

        #region 打卡状态
        private bool GetSwipeState(out int KState, out string StateString, out int duan, string ID)
        {
            bool flag = false;
            int state = -1;
            int _duan = -1;
            string strState = string.Empty;

            try
            {
                if (timeParasInfo != null)
                {
                    DateTime now = DateTime.Now;

                    DateTime BeginStart1 = Convert.ToDateTime(timeParasInfo.BeginStart1.Value.ToLongTimeString());
                    DateTime BeginStop1 = Convert.ToDateTime(timeParasInfo.BeginStop1.Value.ToLongTimeString());
                    DateTime BeginTime1 = Convert.ToDateTime(timeParasInfo.BeginTime1.Value.ToLongTimeString());
                    DateTime EndTime1 = Convert.ToDateTime(timeParasInfo.EndTime1.Value.ToLongTimeString());
                    DateTime EndStart1 = Convert.ToDateTime(timeParasInfo.EndStart1.Value.ToLongTimeString());
                    DateTime EndStop1 = Convert.ToDateTime(timeParasInfo.EndStop1.Value.ToLongTimeString());
                    DateTime BeginDelayTime1 = BeginTime1.AddMinutes(timeParasInfo.BeginDelayTime.Value);
                    DateTime EndForwardTime1 = EndTime1.AddMinutes(-timeParasInfo.EndForwardTime.Value);

                    DateTime BeginStart2 = Convert.ToDateTime(timeParasInfo.BeginStart2.Value.ToLongTimeString());
                    DateTime BeginStop2 = Convert.ToDateTime(timeParasInfo.BeginStop2.Value.ToLongTimeString());
                    DateTime BeginTime2 = Convert.ToDateTime(timeParasInfo.BeginTime2.Value.ToLongTimeString());
                    DateTime EndTime2 = Convert.ToDateTime(timeParasInfo.EndTime2.Value.ToLongTimeString());
                    DateTime EndStart2 = Convert.ToDateTime(timeParasInfo.EndStart2.Value.ToLongTimeString());
                    DateTime EndStop2 = Convert.ToDateTime(timeParasInfo.EndStop2.Value.ToLongTimeString());
                    DateTime BeginDelayTime2 = BeginTime2.AddMinutes(timeParasInfo.BeginDelayTime.Value);
                    DateTime EndForwardTime2 = EndTime2.AddMinutes(-timeParasInfo.EndForwardTime.Value);

                    DateTime BeginStart3 = Convert.ToDateTime(timeParasInfo.BeginStart3.Value.ToLongTimeString());
                    DateTime BeginStop3 = Convert.ToDateTime(timeParasInfo.BeginStop3.Value.ToLongTimeString());
                    DateTime BeginTime3 = Convert.ToDateTime(timeParasInfo.BeginTime3.Value.ToLongTimeString());
                    DateTime EndTime3 = Convert.ToDateTime(timeParasInfo.EndTime3.Value.ToLongTimeString());
                    DateTime EndStart3 = Convert.ToDateTime(timeParasInfo.EndStart3.Value.ToLongTimeString());
                    DateTime EndStop3 = Convert.ToDateTime(timeParasInfo.EndStop3.Value.ToLongTimeString());

                    DateTime BeginDelayTime3 = BeginTime3.AddMinutes(timeParasInfo.BeginDelayTime.Value);
                    DateTime EndForwardTime3 = EndTime3.AddMinutes(-timeParasInfo.EndForwardTime.Value);


                    if (now >= BeginStart1 && now <= BeginStop1)
                    {
                        _duan = 11;
                        if (now <= BeginDelayTime1)
                        {
                            state = 0;
                            strState = "正常上班";
                        }
                        else
                        {
                            state = 1;
                            strState = "上班迟到";
                        }
                    }
                    else if (now >= EndStart1 && now <= EndStop1)
                    {
                        _duan = 12;
                        if (now < EndForwardTime1)
                        {
                            if (!sbll.Exists(ID, 11, now))
                            {
                                _duan = 11;
                                state = 1;
                                strState = "上班迟到";
                            }
                            else
                            {

                                state = 3;
                                strState = "下班早退";
                            }

                        }
                        else
                        {
                            state = 2;
                            strState = "正常下班";
                        }
                    }
                    else if (now >= BeginStart2 && now <= BeginStop2)
                    {
                        _duan = 21;
                        if (now <= BeginDelayTime2)
                        {
                            state = 0;
                            strState = "正常上班";
                        }
                        else
                        {
                            state = 1;
                            strState = "上班迟到";
                        }
                    }
                    else if (now >= EndStart2 && now <= EndStop2)
                    {
                        _duan = 22;
                        if (now < EndForwardTime2)
                        {
                            if (!sbll.Exists(ID, 21, now))
                            {
                                _duan = 21;
                                state = 1;
                                strState = "上班迟到";
                            }
                            else
                            {
                                state = 3;
                                strState = "下班早退";
                            }

                        }
                        else
                        {
                            state = 2;
                            strState = "正常下班";
                        }
                    }
                    else if (now >= BeginStart3 && now <= BeginStop3)
                    {
                        _duan = 31;
                        if (now <= BeginDelayTime3)
                        {
                            state = 0;
                            strState = "正常上班";
                        }
                        else
                        {
                            state = 1;
                            strState = "上班迟到";
                        }
                    }
                    else if (now >= EndStart3 && now <= EndStop3)
                    {
                        _duan = 32;
                        if (now < EndForwardTime3)
                        {
                            if (sbll.Exists(ID, 31, now))
                            {
                                _duan = 31;
                                state = 1;
                                strState = "上班迟到";
                            }
                            else
                            {
                                state = 3;
                                strState = "下班早退";
                            }

                        }
                        else
                        {
                            state = 2;
                            strState = "正常下班";
                        }
                    }
                    else
                    {
                        state = 4;
                        strState = "非打卡时间";
                    }






                    flag = true;
                }

                KState = state;
                StateString = strState;
                duan = _duan;

            }
            catch (Exception ex)
            {

                throw ex;
            }

            return flag;

        }
        #endregion

        private List<SwipeCardRecordInfo> GetFiveMinuteRecord(string empID, int state, int duan)
        {
            string stateStr = string.Empty;

            if (state == 0 || state == 1)
            {
                stateStr = " KState in(0,1)";
            }
            else if (state == 2 || state == 3)
            {
                stateStr = " KState in(2,3)";
            }
            else if (state == 4)
            {
                stateStr = " KState =4";
            }
            else if (state == 5)
            {
                stateStr = " KState =5";
            }
            else
            {
                return null;
            }

            return new SwipeCardRecord().GetModelList(string.Format("EmployeeID='{0}' and {1} and SwipeCardTime>=datetime('{2}') and duan={3}",
                empID,
                stateStr,
                DateTime.Now.AddMinutes(-1).ToString("yyyy-MM-dd hh:mm:ss"),
                duan
                ));
        }



        #region 定时器事件
        private void timer3_Tick(object sender, EventArgs e)
        {
            txtDate.Text = "当前日期：" + DateTime.Now.ToString("yyyy-MM-dd");
            txtTime.Text = "当前时间：" + DateTime.Now.ToLongTimeString();
        }

        private void timer4_Tick(object sender, EventArgs e)
        {
            TimeSpan sp = (TimeSpan)(DateTime.Now - ActionTime);
            if (sp.TotalSeconds > 3)
            {
                txtTip.Text = string.Empty;
                gboxInfo.Visibility = Visibility.Collapsed;
            }
        }


        /// <summary>
        /// 定时器事件，每500毫秒读一次卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!isRuning)
            {
                this.SwipingCard();
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            try
            {
                lock (this.locker)
                {
                    foreach (string ID in this.emplist.Keys)
                    {
                        SwipingInfo item = this.emplist[ID];

                        TimeSpan span = (TimeSpan)(DateTime.Now - item.SwipingTime);
                        if (span.TotalMinutes >= 5)
                        {
                            emplist.Remove(ID);
                        }

                    }
                }

            }
            catch (Exception)
            {
            }
        }

        #endregion


        #region 刷卡
        private void SwipingCard()
        {
            CardFun cardbll = new CardFun();
            Guid uniqueID;
            int state;
            try
            {
                state = cardbll.GetCardUniqueID(ConfigHelper.NewPassword, out uniqueID);

                if (state == 0)
                {
                    this.cardID = uniqueID.ToString();
                    if (this.onID == this.cardID)
                    {
                        return;
                    }

                    //if (emplist.ContainsKey(uniqueID.ToString()))
                    //{
                    //    txtTip.Text = "你好，五分钟内不能重复打卡！";
                    //    ActionTime = DateTime.Now;
                    //    return;
                    //}
                    if (useWebcam)
                    {
                        videoDevice_SnapshotFrame();//读卡成功，触发拍照事件
                    }
                    else
                    {
                        DealWithSwipe(null, uniqueID.ToString());
                    }


                }
                else if (state == 8)
                {
                    this.onID = string.Empty;
                }
                else
                {
                    ShowTip(ConfigHelper.GetRFIDState(state));
                }

            }
            catch (Exception ex)
            {
                Logger.Write("打卡出错了：" + ex.Message);
                txtTip.Text = "打卡出错了";
                ActionTime = DateTime.Now;
            }

        }

        private void DealWithSwipe(Bitmap img, string uniqueID)
        {
            isRuning = true;
            this.onID = this.cardID;
            ICCardManager cardMgr = new ICCardManager();
            ICCardManagerInfo cardInfo;
            Employee empbll = new Employee();
            EmployeeInfo empInfo;
            SwipeCardRecord recordbll = new SwipeCardRecord();
            try
            {
                cardInfo = cardMgr.GetModel(uniqueID.ToString());
                if (cardInfo != null && cardInfo.KState == 0)
                {
                    empInfo = empbll.GetModel(cardInfo.EmployeeID);

                    if (empInfo != null && empInfo.KState == 1)
                    {
                        int sstate = -1;
                        int duan = -1;
                        string stateString = string.Empty;

                        if (!GetSwipeState(out sstate, out stateString, out duan, empInfo.ID))
                        {
                            this.ShowTip("获取状态出错了");
                            ActionTime = DateTime.Now;
                            return;
                        }

                        SwipingInfo swipInfo = new SwipingInfo()
                        {
                            ID = uniqueID.ToString(),
                            Name = empInfo.KName,
                            WorkNum = empInfo.WordNum,
                            SwipingTime = DateTime.Now,
                            kState = stateString
                        };
                        string imgUrl = string.Empty;
                        if (img != null)
                        {
                            imgUrl = SaveImg(empInfo.WordNum, img);
                            if (string.IsNullOrEmpty(imgUrl))
                            {
                                this.ShowTip("保存照片失败");
                            }
                        }
                        SwipeCardRecordInfo recordInfo = new SwipeCardRecordInfo()
                        {
                            ID = Guid.NewGuid().ToString(),
                            EmployeeID = empInfo.ID,
                            SwipeCardTime = swipInfo.SwipingTime,
                            duan = duan,
                            PhotoUrl = imgUrl,
                            KState = sstate,
                            CreateTime = DateTime.Now
                        };

                        List<SwipeCardRecordInfo> slist = GetFiveMinuteRecord(recordInfo.EmployeeID, recordInfo.KState.Value, duan);

                        if (slist != null && slist.Count > 0)
                        {

                            foreach (SwipeCardRecordInfo info in slist)
                            {
                                recordbll.Delete(info.ID);
                                //FileHelper.DeleteFile(FileHelper.GetcurrPath() + "\\" + info.PhotoUrl);
                            }
                        }

                        recordbll.Add(recordInfo);
                        //emplist.Add(swipInfo.ID, swipInfo);



                        var screenInfo = new { swipInfo, recordInfo, empInfo };


                        this.gridsInfo.Dispatcher.Invoke(new Action(() => { this.gridsInfo.DataContext = screenInfo; ; }));
                        this.ShowTip("恭喜，打卡成功！");
                        soundplayer.Play();

                        this.gboxInfo.Dispatcher.Invoke(new Action(() => { this.gboxInfo.Visibility = Visibility.Visible; ; }));
                        ActionTime = DateTime.Now;
                        new CardFun().DoBeed(50);
                    }
                    else if (empInfo == null)
                    {
                        this.ShowTip("该卡没绑定任何员工");
                    }
                    else
                    {
                        this.ShowTip("该员工已离职");
                    }
                }
                else if (cardInfo == null)
                {
                    this.ShowTip("该卡没有在系统登记！");
                }
                else
                {
                    if (cardInfo.KState == 1)
                    {
                        ShowTip("该卡已退还");
                    }
                    else if (cardInfo.KState == 2)
                    {
                        ShowTip("该卡已挂失");
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Write("处理刷卡失败：" + ex.Message);
                //MessageBox.Show("处理刷卡失败：" + ex.Message);
                ShowTip("处理刷卡失败：" + ex.Message);
            }
            finally
            {
                isRuning = false;
            }
        }
        #endregion

        private void ShowTip(string input)
        {
            this.txtTip.Dispatcher.Invoke(new Action(() => { this.txtTip.Text = input; ; }));
        }


        #region 摄像头
        private void Disconnect()
        {
            webcamPlayer.Dispose();
        }



        private void videoDevice_SnapshotFrame()
        {
            Bitmap img = GetBitmap(webcamPlayer.CurrentBitmap);
            if (byHand)
            {
                byHand = false;
                SwipeByHand(img, this.workNumber, this.password);
            }
            else
            {
                DealWithSwipe(img, cardID);
            }
        }

        private Bitmap GetBitmap(BitmapSource source)
        {
            Bitmap bmp = new Bitmap(
              source.PixelWidth,
              source.PixelHeight,
              System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            BitmapData data = bmp.LockBits(
              new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size),
              ImageLockMode.WriteOnly,
              System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            source.CopyPixels(
              Int32Rect.Empty,
              data.Scan0,
              data.Height * data.Stride,
              data.Stride);
            bmp.UnlockBits(data);
            return bmp;
        }



        private string SaveImg(string workNum, Bitmap img)
        {
            string fileName = string.Empty;
            string filePath = string.Empty;
            try
            {
                filePath = @"\Photos\swipeImg\" + workNum + @"\" + DateTime.Now.Month;
                FileHelper.CreateDirectory(FileHelper.GetcurrPath() + "\\" + filePath);
                fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
                img.Save(FileHelper.GetcurrPath() + "\\" + filePath + "\\" + fileName, ImageFormat.Jpeg);
                img.Dispose();

            }

            catch (Exception ex)
            {
                Logger.Write("保存图片失败:" + ex.Message);

            }

            return filePath + "\\" + fileName;
        }

        #endregion



        #region 手工打卡

        private void SwipeByHand(Bitmap img, string workNum, string pwd)
        {
            Employee empbll = new Employee();
            SwipeCardRecord recordbll = new SwipeCardRecord();
            EmployeeInfo empInfo;

            try
            {

                empInfo = empbll.GetModelByNumAndPwd(workNum, pwd);

                if (empInfo != null && empInfo.KState == 1)
                {
                    int sstate = -1;
                    int duan = -1;
                    string stateString = string.Empty;

                    if (!GetSwipeState(out sstate, out stateString, out duan, Guid.Empty.ToString()))
                    {
                        this.ShowTip("获取状态出错了");
                        ActionTime = DateTime.Now;
                        return;
                    }

                    SwipingInfo swipInfo = new SwipingInfo()
                    {
                        ID = "",
                        Name = empInfo.KName,
                        WorkNum = empInfo.WordNum,
                        SwipingTime = DateTime.Now,
                        kState = stateString
                    };
                    string imgUrl = string.Empty;
                    if (img != null)
                    {
                        imgUrl = SaveImg(empInfo.WordNum, img);
                        if (string.IsNullOrEmpty(imgUrl))
                        {
                            this.ShowTip("保存照片失败");
                            ActionTime = DateTime.Now;
                        }
                    }
                    SwipeCardRecordInfo recordInfo = new SwipeCardRecordInfo()
                    {
                        ID = Guid.NewGuid().ToString(),
                        EmployeeID = empInfo.ID,
                        SwipeCardTime = swipInfo.SwipingTime,
                        duan = duan,
                        PhotoUrl = imgUrl,
                        KState = sstate,
                        CreateTime = DateTime.Now
                    };

                    List<SwipeCardRecordInfo> slist = GetFiveMinuteRecord(recordInfo.EmployeeID, recordInfo.KState.Value,duan);

                    if (slist != null && slist.Count > 0)
                    {

                        foreach (SwipeCardRecordInfo info in slist)
                        {
                            recordbll.Delete(info.ID);
                            //FileHelper.DeleteFile(FileHelper.GetcurrPath() + "\\" + info.PhotoUrl);
                        }
                    }

                    recordbll.Add(recordInfo);
                    var screenInfo = new { swipInfo, recordInfo, empInfo };


                    this.gridsInfo.Dispatcher.Invoke(new Action(() => { this.gridsInfo.DataContext = screenInfo; ; }));


                    this.gboxInfo.Dispatcher.Invoke(new Action(() => { this.gboxInfo.Visibility = Visibility.Visible; ; }));
                    ActionTime = DateTime.Now;
                    this.ShowTip("恭喜，打卡成功！");

                }
                else if (empInfo == null)
                {
                    this.ShowTip("用户名或密码错误");
                    ActionTime = DateTime.Now;
                }
                else
                {
                    this.ShowTip("该员工已离职");
                    ActionTime = DateTime.Now;
                }
            }
            catch (Exception ex)
            {
                Logger.Write("手工打卡失败：" + ex.Message);
                ShowTip("手工打卡失败");
                ActionTime = DateTime.Now;
            }
        }

        private void btnSubmit_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(txtWorkNum.Text))
            {
                MessageBox.Show("工号不能为空");
                return;
            }

            if (string.IsNullOrEmpty(txtpwd.Password))
            {
                MessageBox.Show("密码不能为空");
                return;
            }
            this.byHand = true;
            if (useWebcam)
            {
                this.password = txtpwd.Password.Trim();
                this.workNumber = txtWorkNum.Text.Trim();
                videoDevice_SnapshotFrame();//读卡成功，触发拍照事件
            }
            else
            {
                SwipeByHand(null, txtWorkNum.Text.Trim(), txtpwd.Password.Trim());
            }


        }

        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            txtWorkNum.Text = string.Empty;
            txtpwd.Password = string.Empty;
        }

        #endregion


        #region 关闭
        private void Window_Closed(object sender, EventArgs e)
        {
            this.timer1.Stop();
            //this.timer2.Stop();
            this.timer3.Stop();
            this.timer4.Stop();
            this.Disconnect();
        }

        #endregion

        #region 全屏显示
        private void btnFullScreen_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                FullscreenHelper.GoFullscreen(this);
                btnFullScreen.Visibility = Visibility.Collapsed;
            }
            catch (Exception ex)
            {
                MessageBox.Show("全屏显示出错了：" + ex.Message);
            }
        }

        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape && FullscreenHelper.IsFullscreen(this))
            {
                try
                {
                    FullscreenHelper.ExitFullscreen(this);
                    btnFullScreen.Visibility = Visibility.Visible;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("退出全屏出错了：" + ex.Message);
                }
            }
        }
        #endregion

    }
}
